﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;

namespace System.Web.Mvc.Html
{
    /// <summary>
    /// HTML扩展
    /// </summary>
    public static class HtmlHelperEx
    {
        /// <summary>
        /// 获取表达式的属性的值和属性名
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <typeparam name="TKey">属性类型</typeparam>
        /// <param name="helper">htmlHelper</param>
        /// <param name="expression">表达式</param>
        /// <param name="name">属性名</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        /// <returns></returns>
        private static TKey GetExpressionValue<T, TKey>(this HtmlHelper<T> helper, Expression<Func<T, TKey>> expression, out string name)
        {
            if (expression == null)
            {
                throw new ArgumentNullException();
            }

            MemberExpression body = expression.Body as MemberExpression;
            if (body == null || body.Member.DeclaringType.IsAssignableFrom(typeof(T)) == false || body.Expression.NodeType != ExpressionType.Parameter)
            {
                throw new ArgumentException();
            }

            name = body.Member.Name;
            var value = typeof(T).GetProperty(name).GetValue(helper.ViewData.Model, null);
            return (TKey)value;
        }

        /// <summary>
        /// bool类型生成Select下拉框
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="helper">html生成类</param>
        /// <param name="expression">选择器</param>
        /// <param name="trueText">为true时的文本</param>
        /// <param name="falseText">为false时的文本</param>
        /// <param name="htmlAttributes">html属性</param>       
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<T>(this HtmlHelper<T> helper, Expression<Func<T, bool>> expression, string trueText, string falseText, object htmlAttributes = null)
        {
            string name = string.Empty;
            var value = helper.GetExpressionValue<T, bool>(expression, out name);

            var list = new List<SelectListItem>()
            {
                new SelectListItem() { Value = "true", Text = trueText, Selected = value == true },
                new SelectListItem() { Value = "false", Text = falseText, Selected = value == false }
            };
            return helper.DropDownList(name, list, htmlAttributes);
        }


        /// <summary>
        /// bool类型生成Select下拉框
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="helper">html生成类</param>
        /// <param name="expression">选择器</param>
        /// <param name="trueText">为true时的文本</param>
        /// <param name="falseText">为false时的文本</param>
        /// <param name="htmlAttributes">html属性</param>       
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<T>(this HtmlHelper<T> helper, Expression<Func<T, bool>> expression, string trueText, string falseText, IDictionary<string, object> htmlAttributes)
        {
            string name = string.Empty;
            var value = helper.GetExpressionValue<T, bool>(expression, out name);

            var list = new List<SelectListItem>()
            {
                new SelectListItem() { Value = "true", Text = trueText, Selected = value == true },
                new SelectListItem() { Value = "false", Text = falseText, Selected = value == false }
            };
            return helper.DropDownList(name, list, htmlAttributes);
        }

        /// <summary>
        /// 只读文本框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString TextBoxReadonlyFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return htmlHelper.TextBoxFor(expression, new { @readonly = "readonly" });
        }
    }
}